/**
 * Copyright 2011 Honeywell Federal Manufacturing & Technologies, LLC. This material was produced under U.S. Government
 * contract DE-ACO4-01AL66850, Honeywell Federal Manufacturing & Technologies, LLC, (FM&T) with the U. S. Department of
 * Energy for the operation of the Kansas City Plant . The U.S. Government has rights to use, reproduce, and distribute
 * this software.  NEITHER THE GOVERNMENT NOR Honeywell Federal Manufacturing & Technologies, LLC, MAKES ANY WARRANTY,
 * EXPRESS OR IMPLIED, OR ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE.  If software is modified to produce
 * derivative works, such modified software should be clearly marked, so as not to confuse it with the version available
 * from FM&T.
 *
 * Additionally, this program is free software; you can redistribute it and/or modify it under the terms of the GNU
 * General Public License Version 3 published by the Free Software Foundation. Accordingly, this program is distributed in
 * the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with this library.
 * If not, see http://www.gnu.org/licenses/.
 */
package org.braintrain.tapestry.view;

import com.javaforge.tapestry.spring.annotations.InjectSpring;
import org.apache.log4j.Logger;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.annotations.InjectState;
import org.apache.tapestry.html.BasePage;
import org.apache.tapestry.util.exception.ExceptionAnalyzer;
import org.apache.tapestry.util.exception.ExceptionDescription;
import org.apache.tapestry.util.exception.ExceptionProperty;
import org.braintrain.services.MessageService;
import org.braintrain.tapestry.aso.Visit;
import org.hibernate.HibernateException;

import java.sql.SQLException;


/**
 * ErrorPage --- custom error display and exception page
 *
 * @author Robert Engelhardt
 */
public abstract class ErrorPage extends BasePage {

	private static final Logger LOG = Logger.getLogger( ErrorPage.class );
	
	/**
	 * spring injected authorized user service used to verify the current user
	 *
	 * @return the service
	 */
	@InjectSpring("messageService")
	public abstract MessageService getMessageService();
	
	/**
	 * Get the application visit
	 * @return application visit object
	 */
	@InjectState("visit")
	public abstract Visit getVisit();
		
	/**
	 * A list of the stack trace items
	 *
	 * @return a list of the current stack trace
	 */
    public abstract ExceptionDescription[] getExceptions();

	/**
	 * @param elements assignment of found stack trace items
	 */
    public abstract void setExceptions(ExceptionDescription[] exceptions);


	/**
	 * @return the ExceptionDescription
	 */
	public abstract ExceptionDescription getCurrentException();

	/**
	 * @param ExceptionDescription stack trace
	 */
	public abstract void setCurrentException(ExceptionDescription exception);

    /**
     * @return the ExceptionProperty
     */
    public abstract ExceptionProperty getCurrentStackTraceProperties();

    /**
     * @param ExceptionProperty stack trace
     */
    public abstract void setCurrentStackTraceProperties(ExceptionProperty exception);
    
    /**
     * @return the ExceptionProperty
     */
    public abstract String getCurrentStackTrace();

    /**
     * @param ExceptionProperty stack trace
     */
    public abstract void setCurrentStackTrace(String exception);
    
	/**
	 * @return the exception that was thrown
	 */
	public abstract Exception getLocalException();

	/**
	 * exception assignment
	 *
	 * @param exception the exception to report on
	 */
	public abstract void setLocalException(Exception exception);

	/**
	 * @return the exception
	 */
	public Exception getException() {
        
		return getLocalException();
	}

	/**
	 * @param exception the exception
	 */
	public void setException(final Exception exception) {
        
        setLocalException(exception);
                
        ExceptionAnalyzer analyzer = new ExceptionAnalyzer();

        ExceptionDescription[] exceptions = analyzer.analyze(exception);

        setExceptions(exceptions);
	}

	/**
	 * @return the generated header to display
	 */
	public String getErrorHeader() {
		Exception exception = getException();

		if(exception == null) {
			return "This application has encountered an unknown error";
		}

		if(exception instanceof SQLException || exception instanceof HibernateException) {
			return "This application has encountered a database/persistence error";
		}

		return "This application has encountered an error";
	}

	/**
	 * determine if stack trace should be outputted
	 *
	 * @return true if stack trace should be shown
	 */
	public boolean getShowStackTrace() {
		return (getException() != null);
	}

	/**
	 * Listener method that is called by the rendering of the stack trace
	 * @param cycle
	 */
	public void onRenderStacktrace( IRequestCycle cycle ) {
		try {
            for(ExceptionDescription e : getExceptions()){
                LOG.error(e);
            }

			//getMessageService().sendException( getExceptions(), getVisit().getAuthenticatedUser().getProfile().getName().toString() );
		} catch (Exception e) {
			LOG.warn("onRenderStacktrace", e );
		}
	}
}
